package main

import "fmt"

//只有一个defer
func oneDefer()  {
	defer fmt.Println("aaaaaaaaaaaaaaaaaaaaaaaaaaaa")
	fmt.Println("bbbbbbbbbbbbbbbbbbbbbbbbbbbb")
	fmt.Println("cccccccccccccccccccccccccccc")
	fmt.Println("dddddddddddddddddddddddddddd")
}

//多个defer
func moreDefer()  {
	defer fmt.Println("aaaaaaaaaaaaaaaaaaaaaaaaaaaa")
	defer fmt.Println("bbbbbbbbbbbbbbbbbbbbbbbbbbbb")
	defer fmt.Println("cccccccccccccccccccccccccccc")
	defer fmt.Println("dddddddddddddddddddddddddddd")
}

//匿名函数结合defer使用,直接捕获外部变量
func nimingDefer() {
	a, b := 10, 30
	defer func () {
		fmt.Printf("a = %d, b = %d\n", a, b)
	}()
	a = 100
	b = 200
	fmt.Printf("out a = %d, b = %d\n", a, b)
}

//匿名函数结合defer使用,先传入参数
func nimingDefer1()  {
	a, b := 10, 30
	defer func (a, b int) {
		fmt.Printf("a = %d, b = %d\n", a, b)
	}(a, b)
	a = 100
	b = 200
	fmt.Printf("out a = %d, b = %d\n", a, b)
}

func main()  {
	/**
	defer 延迟执行，在函数调用完成的一瞬间执行，相当于析构函数
	多个defer的执行顺序是先进后出
	defer结合匿名函数使用的时候，如果在自调函数时没有传参，那么函数执行的时候如果捕获外部变量发生了变化，打印的变量也会发生变化，因为他是最后执行的，如果在自调时就已经传去了参数，那么就不会改变，因为他在调用时就已经将变量传递给了匿名函数，只是没有调用而已，无论外部变量怎么变化，匿名函数里打印的还是最初的值
	 */
	 oneDefer()
	 fmt.Println("---------------------------------")
	 moreDefer()
	 fmt.Println("---------------------------------")
	 nimingDefer()
	 fmt.Println("---------------------------------")
	 nimingDefer1()
}
